package com.todo.sight.infrastructure.repository.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.todo.common.common.entity.response.page.PageResult;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.exception.BizException;
import com.todo.common.utils.MathUtils;
import com.todo.common.utils.StringUtils;
import com.todo.sight.infrastructure.mapper.SightPoiMapper;
import com.todo.sight.infrastructure.repository.SightPoiRepository;
import com.todo.sight.infrastructure.entity.condition.SightPoiCondition;
import com.todo.sight.infrastructure.entity.po.SightPoiPO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (SightPoi)表服务实现类
 *
 * @author zhangwenxiang
 * @since 2024-03-04 21:10:04
 */
@Slf4j
@Repository("sightPoiRepository")
public class SightPoiRepositoryImpl implements SightPoiRepository {
    @Resource
    private SightPoiMapper sightPoiMapper;


    @Override
    public PageResult<SightPoiPO> querySightPoiByCondition(SightPoiCondition sightPoiCondition) {
        PageResult<SightPoiPO> pageResult = new PageResult<>();
        if (sightPoiCondition == null) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        pageResult.setPageNum(sightPoiCondition.getPageIndex());
        pageResult.setPageSize(sightPoiCondition.getPageSize());
        long count = queryCountByCondition(sightPoiCondition);
        if (count <= 0) {
            return pageResult;
        }
        pageResult.setPageCount((int) MathUtils.divide(count, sightPoiCondition.getPageSize()));
        pageResult.setTotal(count);
        List<SightPoiPO> sightPoiPOList = sightPoiMapper.querySightPoiPOByCondition(sightPoiCondition);
        if (CollectionUtils.isEmpty(sightPoiPOList)) {
            pageResult.setHasNext(false);
            return pageResult;
        }
        pageResult.setResults(sightPoiPOList);
        pageResult.setCurrentIndex(sightPoiPOList.get(0).getId());
        pageResult.setHasNext(sightPoiPOList.size() >= sightPoiCondition.getPageSize());
        return pageResult;
    }

    @Override
    public Long queryCountByCondition(SightPoiCondition sightPoiCondition) {
        if (sightPoiCondition == null || sightPoiCondition.getPageSize() <= 0) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        return sightPoiMapper.queryCountByCondition(sightPoiCondition);
    }

    @Override
    public SightPoiPO querySightPoiPOById(Long id) {
        if (id == null || id < 0) {
            return null;
        }
        return sightPoiMapper.querySightPoiPOById(id);
    }

    @Override
    public Boolean insertSightPoiPO(SightPoiPO sightPoiPO) {
        if (sightPoiPO == null) {
            return false;
        }
        if (!baseFieldCheck(sightPoiPO)) {
            return false;
        }
        return sightPoiMapper.insertSightPoiPO(sightPoiPO) > 0;
    }

    @Override
    @Transactional
    public List<Long> insertSightPoiPOBatch(List<SightPoiPO> sightPoiPOList) {
        if (CollectionUtils.isEmpty(sightPoiPOList)) {
            return Lists.newArrayList();
        }
        List<SightPoiPO> operateList = new ArrayList<>();
        for (SightPoiPO sightPoiPO : sightPoiPOList) {
            if (!baseFieldCheck(sightPoiPO)) {
                continue;
            }
            operateList.add(sightPoiPO);
        }
        if (CollectionUtils.isEmpty(operateList)) {
            return Lists.newArrayList();
        }
        int count = sightPoiMapper.insertBatch(operateList);
        if (count == operateList.size()) {
            return operateList.stream().map(SightPoiPO::getId).collect(Collectors.toList());
        }
        throw new BizException(BizErrorCodeEnum.OPERATION_FAILED);
    }

    @Override
    public Boolean updateSightPoiPOById(SightPoiPO sightPoiPO) {
        if (sightPoiPO == null || sightPoiPO.getId() == null) {
            return false;
        }
        if (!baseFieldCheck(sightPoiPO)) {
            return false;
        }
        return sightPoiMapper.updateSightPoiPOById(sightPoiPO) > 0;
    }


    @Override
    public Boolean removeSightPoiPOById(Long id) {
        if (id == null || id < 0) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        return sightPoiMapper.removeSightPoiPOById(id) > 0;
    }

    @Override
    public SightPoiPO queryPoiByCoordinate(String name, BigDecimal lon, BigDecimal lat) {
        if (StringUtils.isBlank(name) || lon == null || lat == null) {
            return null;
        }
        return sightPoiMapper.queryPoiByCoordinate(name, lon, lat);
    }

    @Override
    public List<SightPoiPO> querySightPoiByName(String name, String city) {
        if (StringUtils.isBlank(name)) {
            return Collections.emptyList();
        }
        return sightPoiMapper.querySightPoiByName(name, city);
    }

    @Override
    public List<SightPoiPO> querySightPoiByIdList(List<Long> poiIdList) {
        if (CollectionUtils.isEmpty(poiIdList)) {
            return Collections.emptyList();
        }
        return sightPoiMapper.querySightPoiByIdList(poiIdList);
    }

    private boolean baseFieldCheck(SightPoiPO sightPoiPO) {
        if (sightPoiPO == null) {
            return false;
        }
        if (sightPoiPO.getLat() == null || sightPoiPO.getLon() == null || sightPoiPO.getName() == null
                || sightPoiPO.getBusinessType() == null || sightPoiPO.getProvince() == null || sightPoiPO.getCity() == null) {
            log.warn("SightPoiRepository#baseFieldCheck 核心字段校验失败，默认不做数据操作 sightPoiPO：【{}】", JSONObject.toJSONString(sightPoiPO));
            return false;
        }
        if (sightPoiPO.getPoiType() == null || sightPoiPO.getTypeList() == null || sightPoiPO.getDistrict() == null || sightPoiPO.getTown() == null) {
            log.warn("SightPoiRepository#baseFieldCheck 基础字段校验失败，默认不做数据操作 sightPoiPO：【{}】", JSONObject.toJSONString(sightPoiPO));
            return false;
        }
        return true;
    }
}
